(function (window) {
    define('framework/colSettings/ColSettingsModule', [
        'angular',
        'underscore'
    ], function (angular, _) {

        function getMainWindow(window) {
            var href = window.location.href;
            if (href.indexOf('__showUrl=true') !== -1) {
                return getMainWindow(window.parent);
            }
            return window;
        }

        return angular.module('ColSettingsModule', [])
            .directive('gColSettings', function ($parse, $rootScope, $window, GillionMsg, GillionLocationService, Arrays,gridLayoutService) {

                var ColSettingsProto = ColSettings.prototype;
                var $style = $('<style>body{overflow:hidden !important;}</style>');

                function ColSettings(scope, element) {
                    var me = this;
                    me.scope = scope;
                    me.element = element;
                    me.selections = {
                        L: [],
                        R: []
                    };
                }

                ColSettingsProto._startSetting = function (grid) {
                    var me = this;
                    me.__currentGrid = grid;
                    me.source = grid.__originalCols || grid.columns;
                    me.selected = [];
                    Arrays.pushAll(grid.columns, me.selected);
                    me.show();
                };

                ColSettingsProto.show = function () {
                    $('head').append($style);
                    var me = this;
                    if (!(me.scope.$$phase || me.scope.$root.$$phase)) {
                        me.scope.$apply(function () {
                            var $element = me.element;
                            $element.show();
                            GillionMsg.mask($element);
                        });
                    } else {
                        me.scope.$evalAsync(function () {
                            var $element = me.element;
                            $element.show();
                            GillionMsg.mask($element);
                        });
                    }
                };

                ColSettingsProto.hide = function () {
                    $style.remove();
                    this.element.hide();
                    GillionMsg.unMask();
                };

                ColSettingsProto.enter = function () {
                    var me = this,
                        enteredCols = me._getSelected();
                    if (_.isEmpty(enteredCols)) {
                        GillionMsg.alert(null, '不允许隐藏所有列。');
                        return;
                    }
                    me.__currentGrid._enterCols(enteredCols);
                    me.hide();
                };

                ColSettingsProto.createLayout = function(title){
                    var me = this,
                        enteredCols = me._getSelected(),
                        tableId = me.__currentGrid.scope.colSettingsKey;
                    me.__currentGrid._enterCols(enteredCols);
                    me.hide();
                    gridLayoutService.createLayout(tableId,title);
                }


                ColSettingsProto.saveLayout = function(){
                    var me = this,
                        enteredCols = me._getSelected(),
                        tableId = me.__currentGrid.scope.colSettingsKey;
                    me.__currentGrid._enterCols(enteredCols);
                    me.hide();
                    gridLayoutService.saveLayout(tableId);
                }

                ColSettingsProto._getSelected = function () {
                    return this.selected;
                };

                ColSettingsProto._getUnSelected = function () {
                    var me = this,
                        selected = me.selected,
                        source = me.source;
                    return _.partial(_.without, source).apply($window, selected);
                };

                ColSettingsProto._addSelection = function ($event, item, type) {
                    var me = this,
                        selections = me.selections;
                    if (!$event.ctrlKey) {
                        selections.L.length = 0;
                        selections.R.length = 0;
                    }
                    selections[type].push(item);
                };

                ColSettingsProto._anySelection = function (item, type) {
                    return _.contains(this.selections[type], item);
                };

                ColSettingsProto._last = function () {
                    var me = this,
                        selected = me.selected,
                        leftSelections = me.selections.L,
                        withoutSelection;
                    withoutSelection = _.partial(_.without, selected).apply($window, leftSelections);
                    me.selected = withoutSelection.concat(leftSelections);
                };

                ColSettingsProto._down = function () {
                    var me = this,
                        selected = me.selected,
                        leftSelections = me.selections.L,
                        i, item;
                    for (i = (selected.length - 2); i >= 0; i--) {
                        item = selected[i];
                        if (_.contains(leftSelections, item)
                            && !_.contains(leftSelections, selected[i + 1])) {
                            selected.splice(i, 1);
                            selected.splice(i + 1, 0, item);
                        }
                    }
                };
                ColSettingsProto._up = function () {
                    var me = this,
                        selected = me.selected,
                        leftSelections = me.selections.L,
                        i, len, item;
                    for (i = 1, len = selected.length; i < len; i++) {
                        item = selected[i];
                        if (_.contains(leftSelections, item)
                            && !_.contains(leftSelections, selected[i - 1])) {
                            selected.splice(i, 1);
                            selected.splice(i - 1, 0, item);
                        }
                    }
                };
                ColSettingsProto._first = function () {
                    var me = this,
                        selected = me.selected,
                        leftSelections = me.selections.L,
                        withoutSelection;
                    withoutSelection = _.partial(_.without, selected).apply($window, leftSelections);
                    me.selected = leftSelections.concat(withoutSelection);
                };

                ColSettingsProto._deselect = function () {
                    var me = this;
                    me.selected = _.partial(_.without, me.selected).apply($window, me.selections.L);
                    me.selections.L.length = 0;
                };

                ColSettingsProto._deselectAll = function () {
                    var me = this;
                    me.selected.length = 0;
                    me.selections.L.length = 0;
                };
                ColSettingsProto._select = function () {
                    var me = this;
                    Arrays.pushAll(me.selections.R, me.selected);
                    me.selections.R.length = 0;
                };
                ColSettingsProto._selectAll = function () {
                    var me = this;
                    me.selected.length = 0;
                    Arrays.pushAll(me.source, me.selected);
                    me.selections.R.length = 0;
                };

                return {
                    restrict: 'E',
                    template: '<div class="table-settings" id="colSettings" style="display: none;">\n    <div class="title"><span class="fl">自定义列表项</span>\n        <button class="fr" ng-click="colSettings.hide()"><i class="iconfont2 icon-guanbi2"></i></button>\n    </div>\n    <div class="body">\n        <div class="box fl">\n            <h3> 已显示列\n                <button ng-click="colSettings._first()" type="button" class="fr">\n                    <i class="iconfont2 icon-dingbu"></i>\n                </button>\n                <button ng-click="colSettings._up()" type="button" class="fr mt-2">\n                    <i class="iconfont2 icon-shangyi"></i>\n                </button>\n                <button ng-click="colSettings._down()" type="button" class="fr mt-2">\n                    <i class="iconfont2 icon-xiayi"></i>\n                </button>\n                <button ng-click="colSettings._last()" type="button" class="fr">\n                    <i class="iconfont2 icon-dibu"></i>\n                </button>\n            </h3>\n            <ul>\n                <li ng-class="{\'act\': colSettings._anySelection(item, \'L\')}"\n                    ng-repeat="item in colSettings._getSelected() track by $id(item)"\n                    ng-click="colSettings._addSelection($event, item, \'L\')">{{item.text}}</li>\n            </ul>\n        </div>\n        <div class="center fl">\n            <a ng-click="colSettings._deselect()" href="javascript:;"><i class="iconfont2 icon-xiangyou"></i></a> \n            <a ng-click="colSettings._deselectAll()" href="javascript:;"><i class="iconfont2 icon-xiangyou2"></i></a> \n            <a ng-click="colSettings._select()" href="javascript:;"><i class="iconfont2 icon-xiangzuo"></i></a> \n            <a ng-click="colSettings._selectAll()" href="javascript:;"><i class="iconfont2 icon-xiangzuo2"></i></a>\n        </div>\n        <div class="box fr"><h3> 未显示列 </h3>\n            <ul>\n                <li ng-class="{\'act\': colSettings._anySelection(item, \'R\')}"\n                    ng-repeat="item in colSettings._getUnSelected() track by $id(item)"\n                    ng-click="colSettings._addSelection($event, item, \'R\')">{{item.text}}</li>\n            </ul>\n        </div>\n    </div>\n    <div class="footer">\n  <a ng-show="!colSettings.__currentGrid.gridLayout.currentLayout && colSettings.__currentGrid.gridLayout" href="javascript:;" class="btn btn-normal" ng-click="colSettings.createLayout(&quot;新增布局&quot;)">新增布局</a> \n  <a ng-show="colSettings.__currentGrid.gridLayout.currentLayout"  href="javascript:;" class="btn btn-normal" ng-click="colSettings.createLayout(&quot;布局另存为&quot;)">布局另存为</a> \n  <a ng-show="colSettings.__currentGrid.gridLayout.currentLayout" href="javascript:;" class="btn btn-normal" ng-click="colSettings.saveLayout()">保存布局</a> \n  <a href="javascript:;" class="btn btn-normal" ng-click="colSettings.enter()">确认</a> \n        <a href="javascript:;" class="btn btn-stroke" ng-click="colSettings.hide()">取消</a>\n    </div>\n</div> ',
                    replace: true,
                    scope: true,
                    link: function (scope, element) {
                        scope.colSettings = new ColSettings(scope, element);
                    }
                };
            })
            .factory('ColSettings', function ($rootScope, $compile) {
                var mainWindow = getMainWindow(window),
                    $dom, $mainBody;
                if(!mainWindow.__colSettings) {
                    $dom = angular.element('<g-col-settings></g-col-settings>');
                    $compile($dom)($rootScope);
                    $mainBody = angular.element(mainWindow.document.body);
                    $mainBody.append($dom);
                    $mainBody.append('<style></style>');
                    mainWindow.__colSettings = $dom.scope().colSettings
                }
                return mainWindow.__colSettings;
            });
    });
}(window));